import fetcher from "../apis/Fetcher";
import {NumberIdAndName} from "../types/BasicModels";
import {
    AddOrderItemKey,
    GoodsSummary,
    QueryGoodsUnitResponse,
    SubGoodsResponse
} from "../apis/GoodsApi";
import {Page, Pageable} from "../utils/Page";
import {OffsetDateTime} from "@js-joda/core";

export function createProcurement(marketId: number) {
    return fetcher.post<number>(`procurementSuppliers/${marketId}/orders`)
}

export function getProcurementDetail(id: number) {
    return fetcher.get<ProcurementDetail>(`procurementSuppliers/orders/${id}`, {
        includeItems: true
    })
}

export function deleteProcurement(id: number) {
    return fetcher.delete(`procurementSuppliers/orders/${id}`)
}

export function getProcurementDetailWithoutItems(id: number) {
    return fetcher.get<ProcurementDetail>(`procurementSuppliers/orders/${id}`)
}

export interface ProcurementDetail {
    id: number
    createdDateTime: OffsetDateTime
    createdBy: NumberIdAndName
    items: Array<ProcurementItem>
    supplier: NumberIdAndName
    submittedDateTime?: OffsetDateTime
    receiptDateTime?: OffsetDateTime
    receiptId?: number
}

export interface ProcurementItem {
    id: number
    name: string
    barcode: string,
    amountInOrder: number
    inStore: number
    boxSpecification?: string
    units: QueryGoodsUnitResponse[]
    subGoods?: SubGoodsResponse
    unit?: NumberIdAndName
    note?: string
    purchasePrice: number
}

export interface AddProcurementItemRequest {
    amount: number
    goodsId: number
    unitId?: number
    subGoodsId?: number
    purchasePrice: number
}

export function addProcurementItem(id: number, addProcurementItemRequest: AddProcurementItemRequest) {
    return fetcher.post(`procurementSuppliers/orders/${id}/items`, {}, addProcurementItemRequest)
}

export function deleteProcurementItemSub(orderId: number, goodsId: number, subGoodsId: number) {
    return fetcher.delete(`procurementSuppliers/orders/${orderId}/items/${goodsId}/sub/${subGoodsId}`)
}

export function deleteProcurementItem(orderId: number, goodsId: number) {
    return fetcher.delete(`procurementSuppliers/orders/${orderId}/items/${goodsId}`)
}

export interface UpdateProcurementItemAmountRequest {
    amount: number
    unitId?: number
}

export function updateProcurementItemAmount(orderId: number, goodsId: number, updateProcurementItemAmountRequest: UpdateProcurementItemAmountRequest) {
    return fetcher.patch(`procurementSuppliers/orders/${orderId}/items/${goodsId}/amount`, {}, updateProcurementItemAmountRequest)
}

export function updateProcurementItemSubAmount(orderId: number, goodsId: number, updateProcurementItemAmountRequest: UpdateProcurementItemAmountRequest, subGoodsId: number) {
    return fetcher.patch(`procurementSuppliers/orders/${orderId}/items/${goodsId}/sub/${subGoodsId}/amount`, {}, updateProcurementItemAmountRequest)
}

export function updateProcurementItemNote(orderId: number, goodsId: number, note: string) {
    return fetcher.patch(`procurementSuppliers/orders/${orderId}/items/${goodsId}/note`, {}, note)
}

export function updateProcurementItemSubNote(orderId: number, goodsId: number, note: string, subGoodsId: number) {
    return fetcher.patch(`procurementSuppliers/orders/${orderId}/items/${goodsId}/sub/${subGoodsId}/note`, {}, note)
}

export function addProcurementItemFromBarcode(orderId: number, barcode: string) {
    return fetcher.post<ProcurementItemInOrderSummary>(`/procurementSuppliers/orders/${orderId}/items/barcodes/${barcode}`)
}

export interface ProcurementItemInOrderSummary {
    goodsId: number,
    name: string,
    barcode: string,
    amountInOrder: number,
    inStore: number,
    boxSpecification: string,
    units: QueryGoodsUnitResponse[],
    unit?: NumberIdAndName,
    subGoods?: SubGoodsResponse,
    purchasePrice: number
    price: number
}

export interface QueryProcurementRequest {
    supplierIds?: number[]
    startDate?: string
    endDate?: string
    createdByIds?: number[]
    status?: ProcurementStatus
}

export function queryProcurements(queryProcurementRequest: QueryProcurementRequest, pageable: Pageable) {
    return fetcher.get<Page<QueryProcurementResponse>>("procurementSuppliers/orders", {...queryProcurementRequest, ...pageable})
}

export interface QueryProcurementResponse {
    id: number
    createdBy: NumberIdAndName
    createdDateTime: OffsetDateTime
    lastModifiedDateTime: OffsetDateTime
    goodsKindAmount: number
    supplier: NumberIdAndName
    status: ProcurementStatus
    receiptId?: number
    note?: string
}

export type ProcurementStatus = keyof typeof procurementStatusMap

export const procurementStatusMap =
    {
        "WAIT_SUBMIT": "待提交",
        "SUBMITTED": "已提交",
        "RECEIPT": "已入库",
    } as const
export const procurementStatuses = Object.keys(procurementStatusMap) as ProcurementStatus[]

export function getAllProcurementCreatedEmployees() {
    return fetcher.get<Array<NumberIdAndName>>("procurementSuppliers/orders/employees", {projection: "summary"})
}

export function submitProcurement(id: number) {
    return fetcher.patch<number>(`procurementSuppliers/orders/${id}/submit`)
}

export function receiptProcurement(id: number) {
    return fetcher.post<number>(`procurementSuppliers/orders/${id}/receipt`)
}

export function findAllGoodsWithHistoryProcurementSupplier(id: number) {
    return fetcher.get<GoodsSummaryWithRememberedPurchasePrice[]>(`procurementSuppliers/${id}/goods`, {
        projection: "withHistoryProcurement",
    })
}

export interface GoodsSummaryWithRememberedPurchasePrice extends GoodsSummary {
    price: number
    rememberedPurchasePrice?: number
    rememberedUnitId?: number
    rememberedAmount?: number
}

interface QueryProcurementSupplierPaymentRecordRequest {
    endPaidDateTime: OffsetDateTime
}

export function queryProcurementSupplierPaymentRecords(supplierId: number, request: QueryProcurementSupplierPaymentRecordRequest) {
    return fetcher.get<QueryProcurementPaymentRecordPageResponse>(`procurements/suppliers/${supplierId}/paymentRecords`, request)
}

export interface QueryProcurementPaymentRecordResponse {
    id: number,
    supplier: NumberIdAndName,
    createdDateTime: OffsetDateTime,
    paidDateTime: OffsetDateTime,
    money: number,
}

export interface QueryProcurementPaymentRecordPageResponse extends Page<QueryProcurementPaymentRecordResponse> {
    totalPaidMoney: number,
    totalNeedPaidMoney: number,
}

interface ProcurementSupplierPaymentRequest {
    money: number,
    paidDateTime: OffsetDateTime
}

export function payProcurement(supplierId: number, request: ProcurementSupplierPaymentRequest) {
    return fetcher.post<ProcurementPayResponse>(`procurements/suppliers/${supplierId}/paymentRecords`, {}, request)
}

interface ProcurementPayResponse {
    id: number,
    createdDateTime: OffsetDateTime,
}

export function deleteProcurementSupplierPaymentRecord(id: number) {
    return fetcher.delete(`procurements/paymentRecords/${id}/`)
}

export function addProcurementItemsFromSubGoodsKeyList(orderId: number, orderItemKeys: AddOrderItemKey[]) {
    return fetcher.post<ProcurementItemInOrderSummary[]>(`/procurementSuppliers/orders/${orderId}/items/batchAdd`, {}, orderItemKeys)
}